/*
    Copyright (c) 2011-2012 Qualcomm Technologies, Inc.  All Rights Reserved.
    Qualcomm Technologies Proprietary and Confidential.
*/

package com.example.widgit;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Camera.Parameters;
import android.os.PowerManager;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;
//TIANYURD zhangwp 20140121 add for CQWB00010199 begin
//TIANYURD zhangwp 20140121 add for CQWB00010199 end

public class CopyOfLEDWidget extends AppWidgetProvider {
    // k-touch,liubzh. Modified for torch brightness. begin
    //public static final byte[] LIGHTE_ON = { '2', '5', '5' };
    public static final byte[] LIGHTE_ON = { '1', '2', '0' };
    // k-touch,liubzh. Modified for torch brightness. end
    public static final byte[] LIGHTE_OFF = { '0' };
    public static final byte[] LIGHT_TORCH = {'1'};
    public static final byte[] LIGHT_DEFAULT = {'0'};

    public final static String TAG = "LEDWidget";
    private static boolean mLightsOn = false;

    // LED light is on or off before pass PowerKey.
    private static boolean mLightsOnBeforePower = false;

    private static Parameters mCameraParas = null;

    private static PowerManager.WakeLock mWakeLock;

    private static boolean mIsLockAcquired = false;

    private final String broadCastString = "qualcomm.android.LEDFlashlight.appWidgetUpdate";
    private final String broadCastPowerKey = "qualcomm.android.LEDFlashlight.LEDUpdate";
    private final String broadCastKilled = "com.android.LEDFlashlight.processKilled";

    // LED node used in different chipsets
    private final static String MSM8226_FLASHLIGHT_BRIGHTNESS =
            "/sys/class/leds/torch-light/brightness";
    private final static String COMMON_FLASHLIGHT_BRIGHTNESS =
            "/sys/class/leds/flashlight/brightness";
    private final static String COMMON_FLASHLIGHT_MODE =
            "/sys/class/leds/flashlight/mode";
    private static boolean DBG = !false;

    //TIANYURD zhangwp 20140121 add for CQWB00010199 begin
    private static int mBatteryLevel = 100;
    private final static int BATTERY_LOW_LEVEL = 5;
    private static boolean mBatteryintentregist = false;

    //TIANYURD zhangwp 20140121 add for CQWB00010199 end

    /**
     * used when remove a wiget
     * */
    // @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        if (DBG)
            Log.v(TAG, "onDeleted");

        super.onDeleted(context, appWidgetIds);
    }

    /**
     * used when the last widget is removed
     * */
    @Override
    public void onDisabled(Context context) {
        if (DBG)
            Log.v(TAG, "onDisabled");
        // When all the widget is deleted, we should assure that the flashlight
        // is turn off.
        // So when all the widget is deleted,if the flashlight state is turn on,
        // turn off it.
        if(mLightsOn){
            mLightsOn = false;
            setLEDStatus(mLightsOn);
        }

        //TIANYURD zhangwp 20140121 add for CQWB00010199 begin
      //  context.getApplicationContext().unregisterReceiver(mIntentReceiver);
        //TIANYURD zhangwp 20140121 add for CQWB00010199 end

        super.onDisabled(context);
    }

    /**
     * used when the widget is created first
     * */
    @Override
    public void onEnabled(Context context) {
        if (DBG)
            Log.v(TAG, "onEnabled");
        //TIANYURD zhangwp 20140121 add for CQWB00010199 begin
        if(mBatteryintentregist==false)
        	{
        	  mBatteryintentregist=true;
	        IntentFilter intentFilter = new IntentFilter();
	        intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED);
	        context.getApplicationContext().registerReceiver(mIntentReceiver, intentFilter);

		}
        //TIANYURD zhangwp 20140121 add for CQWB00010199 end
        super.onEnabled(context);

        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK , "ledflashlight");
    }

    //TIANYURD zhangwp 20140121 add for CQWB00010199 begin
    private BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            String action = intent.getAction();

            if (action.equals(Intent.ACTION_BATTERY_CHANGED)) {
                mBatteryLevel = intent.getIntExtra("level", 0);
                if(mBatteryLevel <= BATTERY_LOW_LEVEL && mLightsOn) {
                    ComponentName mThisWidget = new ComponentName(context,CopyOfLEDWidget.class);
                    RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
                        R.layout.appwidgetlayout);

                    mLightsOn = false;
                    mLightsOnBeforePower = false;
                    updateLEDStatus(context, mRemoteViews, mThisWidget);
                    Toast.makeText(context, context.getString(R.string.battery_low), Toast.LENGTH_LONG).show();
                }
            }
        }
    };
    //TIANYURD zhangwp 20140121 add for CQWB00010199 end

    /**
     * accept broadcast
     * */
    @Override
    public void onReceive(Context context, Intent intent) {
        super.onReceive(context, intent);
        String action = intent.getAction();
        if (broadCastString.equals(action)) {
            // receive a broadcast when opening the camera
            boolean fromCamera = intent.getBooleanExtra("camera_led", false);

            ComponentName mThisWidget = new ComponentName(context,CopyOfLEDWidget.class);
            RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.appwidgetlayout);
            //to avoid invalid pendingIntent after flightmode off->on
            intent.removeExtra("camera_led");
            PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
                intent, 0);
            mRemoteViews.setOnClickPendingIntent(R.id.LEDSwitch, pendingIntent);

            if (DBG)
                Log.d(TAG, "fromCamera = " + fromCamera);

            if (fromCamera) {
                if (mLightsOn) {
                    mLightsOn = false;
                } else {
                    // from the camera, and there is no need to update the
                    // widget
                    // so just return
                    return;
                }
            } else {
                if (DBG)
                    Log.d(TAG, "onSingleTapUp");
                //TIANYURD zhangwp 20140121 add for CQWB00010199 begin
                if(mBatteryLevel <= BATTERY_LOW_LEVEL) {
                    Toast.makeText(context, context.getString(R.string.battery_low), Toast.LENGTH_LONG).show();
                    return;
                }
                //TIANYURD zhangwp 20140121 add for CQWB00010199 end

                mLightsOn = !mLightsOn;

            }
            mLightsOnBeforePower = mLightsOn;
            updateLEDStatus(context, mRemoteViews, mThisWidget);

            return;
        } else if ("android.intent.action.FAST_BOOT_START".equals(action)) {
            Log.d(TAG, "receive the fast boot action");
            // we receive the fast boot action, and we need turn off the led.
            ComponentName mThisWidget = new ComponentName(context,CopyOfLEDWidget.class);
            RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.appwidgetlayout);

            mLightsOn = false;
            mLightsOnBeforePower = false;
            updateLEDStatus(context, mRemoteViews, mThisWidget);
        } else if (action.equals(broadCastPowerKey)) {
            // receive the broadcast when pass PowerKey, and turn off the led.
            boolean fromPowerKey = intent.getBooleanExtra("power_led", false);

            ComponentName mThisWidget = new ComponentName(context, CopyOfLEDWidget.class);
            RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.appwidgetlayout);
            intent.removeExtra("power_led");

            if (mLightsOnBeforePower) {
                mLightsOn = fromPowerKey;
            } else {
                return;
            }

            updateLEDStatus(context, mRemoteViews, mThisWidget);

        } else if (broadCastKilled.equals(action)){
//            String packageName = intent.getStringExtra(Intent.EXTRA_PACKAGES);
//            String currentPackageName = context.getPackageName();
//            if (packageName != null && packageName.equals(currentPackageName)){
//                //when process killed by force close in settings, turn off the led.
//                ComponentName mThisWidget = new ComponentName(context,CopyOfLEDWidget.class);
//                RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
//                        R.layout.appwidgetlayout);
//
//                mLightsOn = false;
//                mLightsOnBeforePower = false;
//                updateLEDStatus(context, mRemoteViews, mThisWidget);
//            }
        }
        //super.onReceive(context, intent);
    }

    private void updateLEDStatus(Context context, RemoteViews remoteView, ComponentName name){

//
//         setLEDStatus(mLightsOn);
//
//         int srcId = mLightsOn?R.drawable.flashlight_on:R.drawable.flashlight_off;
//
//         remoteView.setImageViewResource(R.id.LEDSwitch, srcId);
//         AppWidgetManager.getInstance(context).updateAppWidget(name, remoteView);
    }

    /**
     * used when user action or the widget is placed on the home screen
     * */
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        if (DBG)
            Log.v(TAG, "onUpdate");
        ComponentName mThisWidget = new ComponentName(context,CopyOfLEDWidget.class);
        RemoteViews mRemoteViews = new RemoteViews(context.getPackageName(),
                R.layout.appwidgetlayout);
        // create an intent
        Intent intent = new Intent();
        intent.setAction(broadCastString);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
                intent, 0);
        mRemoteViews.setOnClickPendingIntent(R.id.LEDSwitch, pendingIntent);

        //also update the duplicated LED widget status(when add second LED widget on screen and the previous LED widget is on)
        updateLEDStatus(context , mRemoteViews, mThisWidget);

    }

    private void setLEDStatus(boolean status) {
        FileOutputStream red;
        FileOutputStream mode;

        if (DBG) {
            Log.d(TAG, "current LED status " + status);
        }

        if (mWakeLock != null && status && !mIsLockAcquired) {
            mWakeLock.acquire();

            mIsLockAcquired = status;

        } else if (mWakeLock != null && mIsLockAcquired) {
            mWakeLock.release();

            mIsLockAcquired = status;
        }

        // for MSM8x26, BSP add MSM8226_TORCH_NODE for control torch brightness
        if (isFileExists(MSM8226_FLASHLIGHT_BRIGHTNESS)) {
            changeLEDFlashBrightness(status, MSM8226_FLASHLIGHT_BRIGHTNESS);
        } else {
            changeLEDFlashMode(status, COMMON_FLASHLIGHT_MODE);
            changeLEDFlashBrightness(status, COMMON_FLASHLIGHT_BRIGHTNESS);
        }

    }

    private void changeLEDFlashMode(boolean status, String node) {
        try {
            byte[] ledMode = status ? LIGHT_TORCH : LIGHT_DEFAULT;
            FileOutputStream mode = new FileOutputStream(node);
            mode.write(ledMode);
            mode.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, e.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private void changeLEDFlashBrightness(boolean status, String node) {
        try {
            byte[] ledData = status ? LIGHTE_ON : LIGHTE_OFF;
            FileOutputStream brightness = new FileOutputStream(node);
            brightness.write(ledData);
            brightness.close();
        } catch (FileNotFoundException e) {
            Log.d(TAG, e.toString());
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private boolean isFileExists(String filePath) {
        File file = new File(filePath);
        return file.exists();
    }


}